package org.beetl.support;

import java.util.ArrayList;
import java.util.List;

/**
 * OrderByField.包装orderby sql拼装.
 */
public class OrderByField {

 /** The table name. */
 private String tableName;

 /** The field name. */
 private String fieldName;

 /** The column name. */
 private String columnName;

 /** The is ascending. */
 private boolean isAscending = true;

 /** The name mapper. */
 NameMapper nameMapper;

 /**
  * The Constructor.
  *
  * @param nameMapper
  *         the name mapper
  * @param tableName
  *         the table name
  * @param fieldName
  *         the field name
  * @param isAscending
  *         the is ascending
  */
 public OrderByField(NameMapper nameMapper, String tableName, String fieldName, boolean isAscending) {
  super();
  this.tableName = tableName;
  this.fieldName = nameMapper.getPropertyName(fieldName);
  this.columnName = nameMapper.getColumnName(fieldName);
  this.isAscending = isAscending;
 }

 /**
  * The Constructor.
  *
  * @param nameMapper
  *         the name mapper
  * @param fieldName
  *         the field name
  * @param isAscending
  *         the is ascending
  */
 public OrderByField(NameMapper nameMapper, String fieldName, boolean isAscending) {
  this(nameMapper, "", fieldName, isAscending);
 }

 /**
  * The Constructor.
  *
  * @param nameMapper
  *         the name mapper
  * @param fieldNameAndAscending
  *         the field name and ascending
  */
 public OrderByField(NameMapper nameMapper, String fieldNameAndAscending) {
  if (CommonSupport.contains(fieldNameAndAscending, ".")) {
   this.tableName = CommonSupport.substringBefore(fieldNameAndAscending, ".");
   fieldNameAndAscending = CommonSupport.substringAfter(fieldNameAndAscending, ".");
  }
  String[] parts = CommonSupport.split(fieldNameAndAscending, " ");
  if (parts == null) {
   return;
  }
  if (parts.length > 0) {
   fieldName = nameMapper.getPropertyName(parts[0]);
   this.columnName = nameMapper.getColumnName(fieldName);
  }
  if (parts.length > 1 && CommonSupport.equalsIgnoreCase("DESC", parts[1])) {
   this.isAscending = false;
  }
 }

 /**
  * Gets the field name.
  *
  * @return the field name
  */
 public String getFieldName() {
  return fieldName;
 }

 /**
  * Sets the field name.
  *
  * @param fieldName
  *         the field name
  */
 public void setFieldName(String fieldName) {
  this.fieldName = fieldName;
 }

 /**
  * Gets the column name.
  *
  * @return the column name
  */
 public String getColumnName() {
  return columnName;
 }

 /**
  * Sets the column name.
  *
  * @param columnName
  *         the column name
  */
 public void setColumnName(String columnName) {
  this.columnName = columnName;
 }

 /**
  * Checks if is ascending.
  *
  * @return true, if checks if is ascending
  */
 public boolean isAscending() {
  return isAscending;
 }

 /**
  * Sets the ascending.
  *
  * @param isAscending
  *         the ascending
  */
 public void setAscending(boolean isAscending) {
  this.isAscending = isAscending;
 }

 /**
  * Gets the name mapper.
  *
  * @return the name mapper
  */
 public NameMapper getNameMapper() {
  return nameMapper;
 }

 /**
  * Sets the name mapper.
  *
  * @param nameMapper
  *         the name mapper
  */
 public void setNameMapper(NameMapper nameMapper) {
  this.nameMapper = nameMapper;
 }

 /**
  * Gets the table name.
  *
  * @return the table name
  */
 public String getTableName() {
  return tableName;
 }

 /**
  * Sets the table name.
  *
  * @param tableName
  *         the table name
  */
 public void setTableName(String tableName) {
  this.tableName = tableName;
 }

 /**
  * To sql.
  *
  * @return the string
  */
 public String toSql() {
  StringBuilder sb = new StringBuilder();
  if (CommonSupport.isNotBlank(this.getColumnName())) {
   if (CommonSupport.isNotBlank(this.getTableName())) {
    sb.append(this.getTableName()).append(".");
   }
   sb.append(this.getColumnName());
   if (!this.isAscending) {
    sb.append(" DESC");
   }
  }
  return sb.toString();
 }

 /*
  * (non-Javadoc)
  * 
  * @see java.lang.Object#toString()
  */
 
 public String toString() {
  return "OrderByField [fieldName=" + fieldName + ", columnName=" + columnName + ", isAscending=" + isAscending + "]";
 }

 /**
  * Builds the.
  *
  * @param nameMapper
  *         the name mapper
  * @param orderByCause
  *         the order by cause
  * @return the list< order by field>
  */
 public static List<OrderByField> build(NameMapper nameMapper, String orderByCause) {
  List<OrderByField> orderByFields = new ArrayList<OrderByField>();
  String[] parts = CommonSupport.split(orderByCause, ",");
  if (parts != null && parts.length > 0) {
   for (String part : parts) {
    OrderByField orderByField = new OrderByField(nameMapper, part);
    if (CommonSupport.isNotBlank(orderByField.getFieldName())) {
     orderByFields.add(orderByField);
    }
   }
  }
  return orderByFields;

 }

 /**
  * Builds the order by sql.
  *
  * @param nameMapper
  *         the name mapper
  * @param orderByCause
  *         the order by cause
  * @return the string
  */
 public static String buildOrderBySql(NameMapper nameMapper, String orderByCause) {
  return buildOrderBySql(nameMapper, orderByCause, "");
 }

 /**
  * Builds the order by sql.
  *
  * @param nameMapper
  *         the name mapper
  * @param orderByCause
  *         the order by cause
  * @param tableName
  *         the table name
  * @return the string
  */
 public static String buildOrderBySql(NameMapper nameMapper, String orderByCause, String tableName) {
  StringBuilder sb = new StringBuilder();
  List<OrderByField> orderByFields = build(nameMapper, orderByCause);
  for (int i = 0; i < orderByFields.size(); i++) {
   OrderByField byField = orderByFields.get(i);
   if (CommonSupport.isBlank(byField.getTableName())) {
    byField.setTableName(tableName);
   }
   if (i > 0) {
    sb.append(",");
   }
   sb.append(byField.toSql());
  }
  return sb.toString();
 }

 /**
  * Builds the order by sql.
  *
  * @param nameMapper
  *         the name mapper
  * @param orderByCause
  *         the order by cause
  * @param isAscending
  *         the is ascending
  * @return the string
  */
 public static String buildOrderBySql(NameMapper nameMapper, String orderByCause, boolean isAscending) {
  return buildOrderBySql(nameMapper, orderByCause, "", isAscending);
 }

 /**
  * Builds the order by sql.
  *
  * @param nameMapper
  *         the name mapper
  * @param orderByCause
  *         the order by cause
  * @param tableName
  *         the table name
  * @param isAscending
  *         the is ascending
  * @return the string
  */
 public static String buildOrderBySql(NameMapper nameMapper, String orderByCause, String tableName, boolean isAscending) {
  StringBuilder sb = new StringBuilder();
  List<OrderByField> orderByFields = build(nameMapper, orderByCause);
  for (int i = 0; i < orderByFields.size(); i++) {
   OrderByField byField = orderByFields.get(i);
   if (CommonSupport.isBlank(byField.getTableName())) {
    byField.setTableName(tableName);
   }
   if (i <= orderByFields.size() - 1) {
    byField.setAscending(isAscending);
   }
   if (i > 0) {
    sb.append(",");
   }
   sb.append(byField.toSql());
  }
  return sb.toString();
 }

}
